frida for windows
grandfrida for windows
参考
Frida-Windows 夏洛魂的个人博客
JavaScript API | Frida • A world-class dynamic instrumentation toolkit
1 2 3 4 5 6 7 8 9 10 11 12 13
   | #include<stdio.h> #include<stdint.h>
 
  int add(int a,int b){     return a+b; }
  int main(){     int a=6;     int b=7;     printf("%d",add(a,b)); }
   | 
 
很简单的测试脚本 挨个把官方文档的api都试一试

搞一个开发环境
1 2 3
   | git clone https://github.com/oleavr/frida-agent-example.git  cd frida-agent-example/  npm install
   | 
 
网速慢就直接
1
   | git config --global http.proxy http://127.0.0.1:7897
   | 
 

Process


先给出常见类的几个基础的属性
获取id
1
   | frida -f  test.exe -l .\exp\hook.js
   | 
 
1 2
   | var baseaddres =Process.id console.log(baseaddres)
   | 
 

当面对多线程的时候即可使用
1 2
   | Process.getCurrentThreadId() Process.enumerateThreads()
   | 
 
进行查看
获取地址
1 2 3 4 5 6 7 8
   |  var baseaddress = Process.mainModule; console.log("Main module:", baseaddress); console.log("Base address:", baseaddress.base); console.log("Name:", baseaddress.name); console.log("Path:", baseaddress.path); console.log("Size:", baseaddress.size);
 
 
  | 
 

获取到目前加载的模块
1 2 3 4 5 6 7 8 9 10
   | // 获取目标模块的符号表 var symbols = Process.enumerateModules()
  // 遍历并打印符号信息 symbols.forEach(symbols =>{     console.log('Name:', symbols.name,                  'Type:', symbols.size,                 'Module:', symbols.base,                 'Address:', symbols.path)     })
   | 
 

获取模块地址
Process.findModuleByAddress(address)
Process.getModuleByAddress(address)
Process.findModuleByName(name)
Process.getModuleByName(name)
其实功能都差不多 就是弹不弹异常的区别 get失败返回null find失败直接异常
1 2 3 4 5 6 7 8 9 10
   | // 获取目标模块的符号表 var symbols = Process.findModuleByAddress(0x7ffedc230000) console.log(symbols) // 遍历并打印符号信息
  console.log('Name:', symbols.name,                'Type:', symbols.size,               'Module:', symbols.base,               'Address:', symbols.path);
 
   | 
 
获取module内存的信息
1 2 3 4 5
   | var Moduleaddres = Process.findModuleByName("msvcrt.dll")
  var address=Process.findRangeByAddress(ptr(Moduleaddres.base))
  console.log(address.base,address.size,address.file,address.protection)
  | 
 

Module
hook函数
1 2 3 4 5 6 7 8 9 10
   | var addres =Module.findBaseAddress("test.exe").add(0x1550) console.log(addres) Interceptor.attach(addres,{     onEnter(args){         console.log("yes")     },     onLeave(reda){         console.log(reda)     } })
  | 
 

获取到参数 修改返回值
1 2 3 4 5 6 7 8 9 10
   | var addres =Module.findBaseAddress("test.exe").add(0x1550) console.log(addres) Interceptor.attach(addres,{     onEnter(args){         console.log(args[0],args[1])     },     onLeave(reda){         reda.replace(1000)     } })
  | 
 

获取到导入module信息 返回列表
1 2 3 4 5 6 7 8 9 10
   | // 获取目标模块的导入函数列表 const imports = Module.enumerateImports("test.exe");
  // 遍历并打印所有导入函数 imports.forEach(imp => {   console.log('Name:', imp.name,                'Type:', imp.type,               'Module:', imp.module,               'Address:', imp.address); });
   | 
 

获取导出信息 返回列表
1 2 3 4 5 6 7 8 9
   | // 获取目标模块的导出函数列表 const exports = Module.enumerateExports("msvcrt.dll"); console.log("yes") // 遍历并打印所有导出函数 exports.forEach(exp => {   console.log('Name:', exp.name,               'Type:', exp.type,               'Address:', exp.address); });
   | 
 

获取目标模块的符号表
1 2 3 4 5 6 7 8 9 10
   | // 获取目标模块的符号表 const symbols = Module.enumerateSymbols("msvcrt.dll");
  // 遍历并打印符号信息 symbols.forEach(sym => {   console.log('Name:', sym.name,               'Type:', sym.type,               'Address:', sym.address,               'Size:', sym.size); });
   | 
 

字符串读取api
| API | 
说明 | 
| {NativePointer}.readCString() | 
读取C风格字符串 | 
| {NativePointer}.readAnsiString() | 
读取Ansi字符串 | 
| {NativePointer}.readUtf8String() | 
读取UTF8字符串 | 
| {NativePointer}.readUtf16String() | 
读取UTF16字符串 | 
Frida提供的读取数值API
| API | 
说明 | 
| {}.readInt() | 
从给定地址读取整数 | 
| {}.readUInt() | 
从给定地址读取无符号整数 | 
| {}.readS8() | 
从指定地址读取带符号的8位、16位、32位或64位整数 | 
| {}.readShort() | 
从给定地址读取短整数 | 
| {}.readFloat() | 
从给定地址读取浮点数 | 
| {}.readDouble() | 
从给定地址读取双浮点数 | 
| {}.readLong() | 
从给定地址读取长数字 | 
| {}.readULong() | 
从给定地址读取无符号长数字 | 
| {}.readUShort() | 
从给定地址读取无符号短数 | 
| {}.readUS8() | 
从给定地址读取无符号整数 | 
Frida提供的数值写入API
| API | 
说明 | 
| {}.writeInt() | 
向给定地址写入整数 | 
| {}.writeUInt() | 
向给定地址写入无符号整数 | 
| {}.writeS8() | 
向给定地址写入带符号的8位、16位、32位或64位整数 | 
| {}.writeShort() | 
向给定地址写入短整数 | 
| {}.writeFloat() | 
向给定地址写入浮点数 | 
| {}.writeDouble() | 
向给定地址写入双浮点数 | 
| {}.writeLong() | 
向给定地址写入长数字 | 
| {}.writeULong() | 
向给定地址写入无符号长数字 | 
| {}.writeUShort() | 
向给定地址写入无符号短数 | 
| {}.writeUS8() | 
向给定地址写入无符号整数 | 
Hexdump
1 2 3 4
   | var baseaddres = Process.mainModule console.log(baseaddres.base)
  console.log(hexdump(baseaddres.base, {offset: 0,length: 16,header: false,ansi: true}))
   | 
 
创建本地函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | new NativeFunction(address, returnType, argTypes[, abi])
  //TYPES 可选如下: void pointer int uint long ulong char uchar size_t ssize_t float double int8 uint8 int16 uint16 int32 uint32 int64 uint64 bool
  //ABIS 可选如下: default Windows 32-bit: 	sysv 	stdcall 	thiscall 	fastcall 	mscdecl Windows 64-bit: 	win64 UNIX x86: 	sysv 	unix64 UNIX ARM: 	sysv 	vfp
   | 
 
1 2 3 4 5 6
   | var baseaddres =Process.mainModule console.log(baseaddres.base)
  var myfunction =new NativeFunction(baseaddres.base.add(0x1550),"int",["int","int"])
  console.log(myfunction(1000,1200))
   | 
 

函数替换
使用nterceptor.replace()进行操作
1 2 3 4 5 6
   | var baseaddres =Process.mainModule console.log(baseaddres.base)
  Interceptor.replace(baseaddres.base.add(0x1550),new NativeCallback(function(a,b){     return a*b },'int', ['int', 'int']))
   | 
 

内存扫描
1 2 3
   | //pattern的格式为由空格分隔的16进制字符串 Memory.scan(address, size, pattern, callbacks) Memory.scanSync(address, size, pattern)
   | 
 
寄存器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | var addPtr = Process.mainModule.base.add(0x16F8F0)
  Interceptor.attach(addPtr, {     onEnter (args) {       // console.log('args0:' + args[0]);       // console.log('args1:' + args[1]);
        console.log('args1:' + this.context.rcx.toInt32());       console.log('args2:' + this.context.rdx.toInt32());     } });
  //修改寄存器 // Memory.patchCode(addPtr, Process.pointerSize, function (code) { //   const cw = new X86Writer(code, { pc: addPtr }); //   cw.putMovRegU32('eax', 1234); //   cw.putRet(); //   cw.flush(); // });
   |